﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>

//定义了一个结构体
//struct S
//{
//	char c;
//	int i;
//	double d;
//};
//
//struct Stu
//{
//	char name[20];//名字
//	int age;//年龄
//	char sex[5];//性别
//	char id[20];//学号
//};
//
//int main()
//{
//	//按照结构体的成员顺序进行赋值
//	struct Stu s1 = { "张三",22,"男","123456789" };
//	printf("name: %s\n",s1.name);
//	printf("age: %d\n", s1.age);
//	printf("sex: %s\n", s1.sex);
//	printf("id: %s\n", s1.id);
//
//	printf("\n");
//
//	struct Stu s2 = { .age = 18,.name = "梨花",.id = "563217485",.sex = "女" };
//	printf("name: %s\n", s2.name);
//	printf("age: %d\n", s2.age);
//	printf("sex: %s\n", s2.sex);
//	printf("id: %s\n", s2.id);
//	return 0;
//}


//结构体的特殊声明 —— 不完全声明（匿名结构体）

//struct
//{
//	char ch;
//	int i;
//	float f;
//}a;
//
//struct
//{
//	char ch;
//	int i;
//	float f;
//}* ps;
//
//int main()
//{
//	/*a.ch = 'a';
//	b.ch = 'b';
//	printf("%c %c\n",a.ch, b.ch);*/
//	ps = &a; //这里会报出警告，原因是匿名结构体类型即使里面的成员乃至顺序一模一样，但是编译器依然会将它视作为不同的结构体类型
//
//	return 0;
//}


//struct
//{
//	int i;
//	char ch;
//	double d;
//}s;
//
//struct
//{
//	int i;
//	char ch;
//	double d;
//}*ps;
//
//int main()
//{
//	ps = &s;
//	return 0;
//}

//结构体的自引用
//所谓结构体的自引用，就是结构体里自己引用自己，但是这种引用是有规范的，用的是结构体指针来引用
//为什么会只能用结构体指针呢？


//struct Node
//{
//	int data;
//	struct S next;
//};
////结构体里面包含着一个结构体，里面的结构体又包含着一个与自己一样的结构体，有种死递归的感觉
////换句话说，这个结构体的大小是无穷大的
////所以这一种写法是有问题的
//
////那不妨这样想一想，我们既让想要这个结点能够访问到下一个节点的内容，我们不能用自身的结构体
//// 但是我们可以用结构体指针来作为指针域，这样的话就不会出出现上述那种出现大小为无穷大的情况
////结点（结构体的自引用）
//struct Node
//{
//	int data;//数据域
//	struct S* next;//指针域
//};


//能够这样写吗？
typedef struct Node
{
	int data;//数据域
	Node* next;//指针域
}Node;

//答案是不能的，原因是：编译器是从上往下来执行代码的，当执行到 Node* next 这条语句时，编译器由于还未完全读到typedef的
//所有语句，因此就将Node视作未定义的标识符

//正确的写法
//typedef struct Node
//{
//	int data;//数据域
//	struct Node* next;//指针域
//}Node;




//重点：结构体的内存对齐
//结构体里面的成员，并不是向我们所想的那样在内存中是连续存放的，他是存在对齐现象的
//为此，我们就把这种现象称作为结构体内存对齐

//对齐规则：
//1.第一个成员的大小，是从偏移量为0的地方开始存放。
//2.其他成员变量要对⻬到某个数字（对⻬数）的整数倍的地址处。
//  对⻬数 = 编译器默认的⼀个对⻬数 与 该成员变量⼤⼩的较⼩值。
//	- VS 中默认的值为 8
//	-Linux中 gcc 没有默认对⻬数，对⻬数就是成员⾃⾝的⼤⼩
//3.结构体的总大小为最大对齐数（结构体中每个成员变量都有⼀个对⻬数，所有对⻬数中最⼤的）的整数倍
//4.当存在嵌套结构体时，，嵌套的结构体成员对⻬到⾃⼰的成员中最⼤对⻬数的整数倍处，结构
//体的整体⼤⼩就是所有最⼤对⻬数（含嵌套结构体中成员的对⻬数）的整数倍。

//struct S1
//{
//	char c1; // 1   8   1
//	int i;	//  4   8   4
//	char c2;//  1   8   1
//};
//
//struct S2
//{
//	char c1; // 1   8   1
//	char c2;//  1   8   1
//	int i;	//  4   8   4
//};
//
//struct S3
//{
//	double d; //8   8   8
//	char ch;  //1   8   1
//	int i;    //4   8   4
//};
//
//struct S4
//{
//	char c1;        //1    8    1
//	struct S3 s3;	//16  --  8
//	double d;		//8    8    8
//};
//
//int main()
//{
//	printf("%zd\n", sizeof(struct S1));
//	printf("%zd\n", sizeof(struct S2));
//	printf("%zd\n", sizeof(struct S3));
//	printf("%zd\n", sizeof(struct S4));
//
//	
//}
